{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 从环境变量中读取密钥\n",
    "### Read the key from the environment variable\n",
    "- 注意：尽量将你的OpenAI Key存储在类似.env文件中，而不是明文暴露在代码里，这是一种基本的安全措施\n",
    "- Note: Try to store your OpenAI Key in something like an .env file, rather than exposing it explicitly in code, as a basic safety measure!\n",
    "******"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "# Load environment variables from openai.env file\n",
    "load_dotenv(\"asset/openai.env\")\n",
    "\n",
    "# Read the OPENAI_API_KEY from the environment\n",
    "api_key = os.getenv(\"OPENAI_API_KEY\")\n",
    "api_base = os.getenv(\"OPENAI_API_BASE\")\n",
    "os.environ[\"OPENAI_API_KEY\"] = api_key\n",
    "os.environ[\"OPENAI_API_BASE\"] = api_base\n",
    "os.environ[\"SERPAPI_API_KEY\"] = os.getenv(\"SERPAPI_API_KEY\")\n",
    "os.environ[\"ELEVEN_API_KEY\"] = os.getenv(\"ELEVEN_API_KEY\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 如何加载使用tool\n",
    "###  How to load a use tool\n",
    "- 加载预制tool的方法\n",
    "- Ways to load a pre-made tool\n",
    "- 几种tool的使用方式\n",
    "- Several ways to use a tool\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- langchain预制了大量的tools，基本这些工具能满足大部分需求，https://github.com/langchain-ai/langchain/tree/v0.0.352/docs/docs/integrations/tools\n",
    "- Langchain has pre-built a large number of tools, which can basically meet most needs, https://github.com/langchain-ai/langchain/tree/v0.0.352/docs/docs/integrations/tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加预制工具的方法很简单\n",
    "#from langchain.agents import load_tools\n",
    "#tool_names = [...]\n",
    "#tools = load_tools(tool_names) #使用load方法\n",
    "#有些tool需要单独设置llm\n",
    "#from langchain.agents import load_tools\n",
    "#tool_names = [...]\n",
    "#llm = ...\n",
    "#tools = load_tools(tool_names, llm=llm) #在load的时候指定llm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### SerpAPI\n",
    "- 最常见的聚合搜索引擎 https://serper.dev/dashboard\n",
    "### SerpAPI\n",
    "- The most common aggregated search engines https://serper.dev/dashboard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Barack Hussein Obama II'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.utilities import SerpAPIWrapper\n",
    "search = SerpAPIWrapper()\n",
    "search.run(\"Obama's first name?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 支持自定义参数，比如将引擎切换到bing，设置搜索语言等\n",
    "- Support for customization parameters, such as switching the engine to bing, setting the search language, etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'[\\'Barack Hussein Obama II is an American politician who served as the 44th president of the United States from 2009 to 2017. As a member of the Democratic Party, he was the first African-American presi…New content will be added above the current area of focus upon selectionBarack Hussein Obama II is an American politician who served as the 44th president of the United States from 2009 to 2017. As a member of the Democratic Party, he was the first African-American president in U.S. history. Obama previously served as a U.S. senator representing Illinois from 2005 to 2008 and as an Illinois state senator from 1997 to 2004.Wikipediabarackobama.com\\', \\'Barack Obama type: 44th President of the USA.\\', \\'In 1975, when Obama started high school in Hawaii, teacher Eric Kusunoki read the roll call and stumbled on Obama\\\\\\'s first name. \"Is Barack here?\" he asked, pronouncing it BAR-rack .\\', \"Barack Obama, the 44th president of the United States, was born on August 4, 1961, in Honolulu, Hawaii to Barack Obama, Sr. (1936–1982) (born in Oriang\\' Kogelo of Rachuonyo North District, Kenya) and Stanley Ann Dunham, known as Ann (1942–1995) (born in Wichita, Kansas, United States). Obama spent most of his childhood years in Honolulu, where his mother attended the University of Hawaii at Manoa\", \\'https://www.britannica.com/biography/Barack-Obama\\', \\'https://www.history.com/topics/us-presidents/barack-obama\\', \\'Barack Obama is named after his father, who was a Kenyan economist (called under the same name). He’s first real given name is “Barak”, also spelled Baraq (Not to be confused with Barack which is is a building or …\\', \\'Barack Obama is the first Black president of the United States. Learn facts about him: his age, height, leadership legacy, quotes, family, and more.\\', \\'US President Barack Obama\\\\\\'s birth certificate, published on Wednesday, names him as \"Barack Hussein Obama, II\". Why does he qualify for the Roman numerals?\\', \\'On November 4, 2008, Obama became the first African-American to be elected President. He resigned his seat in the U.S. Senate on November 16, 2008. Barack Obama was inaugurated as the 44th President of the …\\', \\'Barack Obama. When Barack Obama was elected president in 2008, he became the first African American to hold the office. Obama faced major challenges during his two-term tenure in office.\\', \\'Barack Obama (born August 4, 1961) is an American politician who served as the 44th president of the United States, the first Black man to do so. Prior to that, he was a civil rights lawyer, …\\']'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "params = {\n",
    "    \"engine\": \"bing\",\n",
    "    \"gl\": \"us\",\n",
    "    \"hl\": \"en\",\n",
    "}\n",
    "search = SerpAPIWrapper(params=params)\n",
    "search.run(\"Obama's first name?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用Dall-E\n",
    "- Dall-E是openai出品的文到图AI大模型\n",
    "### Using Dall-E\n",
    "- Dall-E is a text-to-graph AI macromodel from openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-4-1106-preview\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mTo create the requested image, I will use the Dall-E-Image-Generator.\n",
      "\n",
      "Action: Dall-E-Image-Generator\n",
      "Action Input: A haunted museum on a Halloween night with spooky decorations, ghosts, and jack-o'-lanterns.\u001B[0m\n",
      "Observation: \u001B[36;1m\u001B[1;3mhttps://oaidalleapiprodscus.blob.core.windows.net/private/org-xuYK4AdPRQi7wMYrLz9RUk4e/jn/img-pNkayn8KFwghCLDIx9F8kdrv.png?st=2024-09-20T05%3A23%3A47Z&se=2024-09-20T07%3A23%3A47Z&sp=r&sv=2024-08-04&sr=b&rscd=inline&rsct=image/png&skoid=d505667d-d6c1-4a0a-bac7-5c84a87759f8&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-09-19T23%3A31%3A37Z&ske=2024-09-20T23%3A31%3A37Z&sks=b&skv=2024-08-04&sig=XBOSFl1lIPKagrfK3Qbpt0kjgvFv4o8T0qGD6US9Mtw%3D\u001B[0m\n",
      "Thought:\u001B[32;1m\u001B[1;3mI now know the final answer\n",
      "Final Answer: The image has been successfully created and depicts a haunted museum on a Halloween night with spooky decorations, ghosts, and jack-o'-lanterns.\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    }
   ],
   "source": [
    "from langchain.agents import initialize_agent, load_tools\n",
    "# 需要有dalle模型权限\n",
    "tools = load_tools([\"dalle-image-generator\"])\n",
    "agent = initialize_agent(\n",
    "    tools, \n",
    "    llm, \n",
    "    agent=\"zero-shot-react-description\",\n",
    "    verbose=True\n",
    ")\n",
    "output = agent.invoke(\"Create an image of a halloween night at a haunted museum\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Eleven Labs Text2Speech\n",
    "- ElevenLabs 是非常优秀的TTS合成API\n",
    "### Eleven Labs Text2Speech\n",
    "- ElevenLabs is a great TTS synthesis API!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 插入APIKEY\n",
    "- Insert APIKEY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found existing installation: elevenlabs 0.2.26\n",
      "Uninstalling elevenlabs-0.2.26:\n",
      "  Successfully uninstalled elevenlabs-0.2.26\n",
      "Collecting elevenlabs==0.2.26\n",
      "  Obtaining dependency information for elevenlabs==0.2.26 from https://files.pythonhosted.org/packages/2c/3b/246a4be07b0b8423b8cb228adda91404be9f42fae91f1bdb840c02a94c97/elevenlabs-0.2.26-py3-none-any.whl.metadata\n",
      "  Using cached elevenlabs-0.2.26-py3-none-any.whl.metadata (805 bytes)\n",
      "Requirement already satisfied: pydantic>=2.0 in .\\langchain_v0.1\\lib\\site-packages (from elevenlabs==0.2.26) (2.9.2)\n",
      "Requirement already satisfied: ipython>=7.0 in .\\langchain_v0.1\\lib\\site-packages (from elevenlabs==0.2.26) (8.27.0)\n",
      "Requirement already satisfied: requests>=2.20 in .\\langchain_v0.1\\lib\\site-packages (from elevenlabs==0.2.26) (2.32.3)\n",
      "Requirement already satisfied: websockets>=11.0 in .\\langchain_v0.1\\lib\\site-packages (from elevenlabs==0.2.26) (13.0.1)\n",
      "Requirement already satisfied: decorator in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (5.1.1)\n",
      "Requirement already satisfied: jedi>=0.16 in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (0.19.1)\n",
      "Requirement already satisfied: matplotlib-inline in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (0.1.7)\n",
      "Requirement already satisfied: prompt-toolkit<3.1.0,>=3.0.41 in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (3.0.47)\n",
      "Requirement already satisfied: pygments>=2.4.0 in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (2.18.0)\n",
      "Requirement already satisfied: stack-data in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (0.6.3)\n",
      "Requirement already satisfied: traitlets>=5.13.0 in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (5.14.3)\n",
      "Requirement already satisfied: colorama in .\\langchain_v0.1\\lib\\site-packages (from ipython>=7.0->elevenlabs==0.2.26) (0.4.6)\n",
      "Requirement already satisfied: annotated-types>=0.6.0 in .\\langchain_v0.1\\lib\\site-packages (from pydantic>=2.0->elevenlabs==0.2.26) (0.7.0)\n",
      "Requirement already satisfied: pydantic-core==2.23.4 in .\\langchain_v0.1\\lib\\site-packages (from pydantic>=2.0->elevenlabs==0.2.26) (2.23.4)\n",
      "Requirement already satisfied: typing-extensions>=4.6.1 in .\\langchain_v0.1\\lib\\site-packages (from pydantic>=2.0->elevenlabs==0.2.26) (4.12.2)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in .\\langchain_v0.1\\lib\\site-packages (from requests>=2.20->elevenlabs==0.2.26) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in .\\langchain_v0.1\\lib\\site-packages (from requests>=2.20->elevenlabs==0.2.26) (3.10)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in .\\langchain_v0.1\\lib\\site-packages (from requests>=2.20->elevenlabs==0.2.26) (2.2.3)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in .\\langchain_v0.1\\lib\\site-packages (from requests>=2.20->elevenlabs==0.2.26) (2024.8.30)\n",
      "Requirement already satisfied: parso<0.9.0,>=0.8.3 in .\\langchain_v0.1\\lib\\site-packages (from jedi>=0.16->ipython>=7.0->elevenlabs==0.2.26) (0.8.4)\n",
      "Requirement already satisfied: wcwidth in .\\langchain_v0.1\\lib\\site-packages (from prompt-toolkit<3.1.0,>=3.0.41->ipython>=7.0->elevenlabs==0.2.26) (0.2.13)\n",
      "Requirement already satisfied: executing>=1.2.0 in .\\langchain_v0.1\\lib\\site-packages (from stack-data->ipython>=7.0->elevenlabs==0.2.26) (2.1.0)\n",
      "Requirement already satisfied: asttokens>=2.1.0 in .\\langchain_v0.1\\lib\\site-packages (from stack-data->ipython>=7.0->elevenlabs==0.2.26) (2.4.1)\n",
      "Requirement already satisfied: pure-eval in .\\langchain_v0.1\\lib\\site-packages (from stack-data->ipython>=7.0->elevenlabs==0.2.26) (0.2.3)\n",
      "Requirement already satisfied: six>=1.12.0 in .\\langchain_v0.1\\lib\\site-packages (from asttokens>=2.1.0->stack-data->ipython>=7.0->elevenlabs==0.2.26) (1.16.0)\n",
      "Using cached elevenlabs-0.2.26-py3-none-any.whl (14 kB)\n",
      "Installing collected packages: elevenlabs\n",
      "Successfully installed elevenlabs-0.2.26\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 23.2.1 -> 24.2\n",
      "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
     ]
    }
   ],
   "source": [
    "! pip uninstall elevenlabs -y\n",
    "! pip install elevenlabs==0.2.26"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 工具使用\n",
    "- Tool Use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'eleven_labs_text2speech'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_community.tools import ElevenLabsText2SpeechTool\n",
    "\n",
    "text_to_speak = \"Hello! 你好! Hola! नमस्ते! Bonjour! こんにちは! مرحبا! 안녕하세요! Ciao! Cześć! Привіт! வணக்கம்!\"\n",
    "\n",
    "tts = ElevenLabsText2SpeechTool(\n",
    "    voice=\"Bella\",\n",
    "    text_to_speak=text_to_speak,\n",
    "    verbose=True\n",
    ")\n",
    "tts.name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "Error while running ElevenLabsText2SpeechTool: Invalid API key",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mAPIError\u001B[0m                                  Traceback (most recent call last)",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\langchain_community\\tools\\eleven_labs\\text2speech.py:58\u001B[0m, in \u001B[0;36mElevenLabsText2SpeechTool._run\u001B[1;34m(self, query, run_manager)\u001B[0m\n\u001B[0;32m     57\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m---> 58\u001B[0m     speech \u001B[38;5;241m=\u001B[39m \u001B[43melevenlabs\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mgenerate\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtext\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mquery\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     59\u001B[0m     \u001B[38;5;28;01mwith\u001B[39;00m tempfile\u001B[38;5;241m.\u001B[39mNamedTemporaryFile(\n\u001B[0;32m     60\u001B[0m         mode\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mbx\u001B[39m\u001B[38;5;124m\"\u001B[39m, suffix\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m.wav\u001B[39m\u001B[38;5;124m\"\u001B[39m, delete\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[0;32m     61\u001B[0m     ) \u001B[38;5;28;01mas\u001B[39;00m f:\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\elevenlabs\\simple.py:73\u001B[0m, in \u001B[0;36mgenerate\u001B[1;34m(text, api_key, voice, model, stream, latency, stream_chunk_size)\u001B[0m\n\u001B[0;32m     72\u001B[0m \u001B[38;5;28;01massert\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(text, \u001B[38;5;28mstr\u001B[39m)\n\u001B[1;32m---> 73\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mTTS\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mgenerate\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtext\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mvoice\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mapi_key\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mapi_key\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\elevenlabs\\api\\tts.py:45\u001B[0m, in \u001B[0;36mTTS.generate\u001B[1;34m(text, voice, model, api_key)\u001B[0m\n\u001B[0;32m     40\u001B[0m data \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mdict\u001B[39m(\n\u001B[0;32m     41\u001B[0m     text\u001B[38;5;241m=\u001B[39mtext,\n\u001B[0;32m     42\u001B[0m     model_id\u001B[38;5;241m=\u001B[39mmodel\u001B[38;5;241m.\u001B[39mmodel_id,\n\u001B[0;32m     43\u001B[0m     voice_settings\u001B[38;5;241m=\u001B[39mvoice\u001B[38;5;241m.\u001B[39msettings\u001B[38;5;241m.\u001B[39mmodel_dump() \u001B[38;5;28;01mif\u001B[39;00m voice\u001B[38;5;241m.\u001B[39msettings \u001B[38;5;28;01melse\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[0;32m     44\u001B[0m )  \u001B[38;5;66;03m# type: ignore\u001B[39;00m\n\u001B[1;32m---> 45\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[43mAPI\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mpost\u001B[49m\u001B[43m(\u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mjson\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mdata\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mapi_key\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mapi_key\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     46\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m response\u001B[38;5;241m.\u001B[39mcontent\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\elevenlabs\\api\\base.py:75\u001B[0m, in \u001B[0;36mAPI.post\u001B[1;34m(url, *args, **kwargs)\u001B[0m\n\u001B[0;32m     73\u001B[0m \u001B[38;5;129m@staticmethod\u001B[39m\n\u001B[0;32m     74\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mpost\u001B[39m(url: \u001B[38;5;28mstr\u001B[39m, \u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs):\n\u001B[1;32m---> 75\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mAPI\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrequest\u001B[49m\u001B[43m(\u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmethod\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mpost\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\elevenlabs\\api\\base.py:67\u001B[0m, in \u001B[0;36mAPI.request\u001B[1;34m(url, method, api_key, **kwargs)\u001B[0m\n\u001B[0;32m     65\u001B[0m         \u001B[38;5;28;01mraise\u001B[39;00m AuthorizationError(message)\n\u001B[1;32m---> 67\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m APIError(message, status)\n",
      "\u001B[1;31mAPIError\u001B[0m: Invalid API key",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001B[1;31mRuntimeError\u001B[0m                              Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[17], line 1\u001B[0m\n\u001B[1;32m----> 1\u001B[0m speech_file \u001B[38;5;241m=\u001B[39m \u001B[43mtts\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrun\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtext_to_speak\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\langchain_core\\tools.py:452\u001B[0m, in \u001B[0;36mBaseTool.run\u001B[1;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, **kwargs)\u001B[0m\n\u001B[0;32m    450\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m (\u001B[38;5;167;01mException\u001B[39;00m, \u001B[38;5;167;01mKeyboardInterrupt\u001B[39;00m) \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[0;32m    451\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_tool_error(e)\n\u001B[1;32m--> 452\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m e\n\u001B[0;32m    453\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m    454\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_tool_end(observation, color\u001B[38;5;241m=\u001B[39mcolor, name\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\langchain_core\\tools.py:409\u001B[0m, in \u001B[0;36mBaseTool.run\u001B[1;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, **kwargs)\u001B[0m\n\u001B[0;32m    406\u001B[0m     parsed_input \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_parse_input(tool_input)\n\u001B[0;32m    407\u001B[0m     tool_args, tool_kwargs \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_to_args_and_kwargs(parsed_input)\n\u001B[0;32m    408\u001B[0m     observation \u001B[38;5;241m=\u001B[39m (\n\u001B[1;32m--> 409\u001B[0m         \u001B[43mcontext\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrun\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m    410\u001B[0m \u001B[43m            \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_run\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mtool_args\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mrun_manager\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mtool_kwargs\u001B[49m\n\u001B[0;32m    411\u001B[0m \u001B[43m        \u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    412\u001B[0m         \u001B[38;5;28;01mif\u001B[39;00m new_arg_supported\n\u001B[0;32m    413\u001B[0m         \u001B[38;5;28;01melse\u001B[39;00m context\u001B[38;5;241m.\u001B[39mrun(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_run, \u001B[38;5;241m*\u001B[39mtool_args, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mtool_kwargs)\n\u001B[0;32m    414\u001B[0m     )\n\u001B[0;32m    415\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m ValidationError \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[0;32m    416\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mhandle_validation_error:\n",
      "File \u001B[1;32me:\\教程\\imooc\\langchan_course\\langchain_v0.1\\Lib\\site-packages\\langchain_community\\tools\\eleven_labs\\text2speech.py:65\u001B[0m, in \u001B[0;36mElevenLabsText2SpeechTool._run\u001B[1;34m(self, query, run_manager)\u001B[0m\n\u001B[0;32m     63\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m f\u001B[38;5;241m.\u001B[39mname\n\u001B[0;32m     64\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m---> 65\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mRuntimeError\u001B[39;00m(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mError while running ElevenLabsText2SpeechTool: \u001B[39m\u001B[38;5;132;01m{\u001B[39;00me\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m)\n",
      "\u001B[1;31mRuntimeError\u001B[0m: Error while running ElevenLabsText2SpeechTool: Invalid API key"
     ]
    }
   ],
   "source": [
    "speech_file = tts.run(text_to_speak)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tts.play(speech_file) #需要安装ffmpeg才能播放\n",
    "#tts.stream_speech(text_to_speak)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### GraphQL\n",
    "- 一种api查询语言，类似sql，我们用它来查询奈飞的数据库，查找一下和星球大战相关的电影，API地址https://swapi-graphql.netlify.app/.netlify/functions/index\n",
    "### GraphQL\n",
    "- An api query language, similar to sql, we use it to query Nifty's database for Star Wars related movies, API address https://swapi-graphql.netlify.app/.netlify/functions/index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting gql==3.5.0\n",
      "  Obtaining dependency information for gql==3.5.0 from https://files.pythonhosted.org/packages/74/fb/01a200e1c31b79690427c8e983014e4220d2652b4372a46fe4598e1d7a8e/gql-3.5.0-py2.py3-none-any.whl.metadata\n",
      "  Using cached gql-3.5.0-py2.py3-none-any.whl.metadata (9.2 kB)\n",
      "Collecting graphql-core<3.3,>=3.2 (from gql==3.5.0)\n",
      "  Obtaining dependency information for graphql-core<3.3,>=3.2 from https://files.pythonhosted.org/packages/d1/33/cc72c4c658c6316f188a60bc4e5a91cd4ceaaa8c3e7e691ac9297e4e72c7/graphql_core-3.2.4-py3-none-any.whl.metadata\n",
      "  Using cached graphql_core-3.2.4-py3-none-any.whl.metadata (10 kB)\n",
      "Requirement already satisfied: yarl<2.0,>=1.6 in .\\langchain_v0.1\\lib\\site-packages (from gql==3.5.0) (1.11.1)\n",
      "Requirement already satisfied: backoff<3.0,>=1.11.1 in .\\langchain_v0.1\\lib\\site-packages (from gql==3.5.0) (2.2.1)\n",
      "Requirement already satisfied: anyio<5,>=3.0 in .\\langchain_v0.1\\lib\\site-packages (from gql==3.5.0) (4.5.0)\n",
      "Requirement already satisfied: idna>=2.8 in .\\langchain_v0.1\\lib\\site-packages (from anyio<5,>=3.0->gql==3.5.0) (3.10)\n",
      "Requirement already satisfied: sniffio>=1.1 in .\\langchain_v0.1\\lib\\site-packages (from anyio<5,>=3.0->gql==3.5.0) (1.3.1)\n",
      "Requirement already satisfied: multidict>=4.0 in .\\langchain_v0.1\\lib\\site-packages (from yarl<2.0,>=1.6->gql==3.5.0) (6.1.0)\n",
      "Using cached gql-3.5.0-py2.py3-none-any.whl (74 kB)\n",
      "Using cached graphql_core-3.2.4-py3-none-any.whl (203 kB)\n",
      "Installing collected packages: graphql-core, gql\n",
      "Successfully installed gql-3.5.0 graphql-core-3.2.4\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 23.2.1 -> 24.2\n",
      "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
     ]
    }
   ],
   "source": [
    "! pip install gql==3.5.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: requests_toolbelt==1.0.0 in .\\langchain_v0.1\\lib\\site-packages (1.0.0)\n",
      "Requirement already satisfied: requests<3.0.0,>=2.0.1 in .\\langchain_v0.1\\lib\\site-packages (from requests_toolbelt==1.0.0) (2.32.3)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in .\\langchain_v0.1\\lib\\site-packages (from requests<3.0.0,>=2.0.1->requests_toolbelt==1.0.0) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in .\\langchain_v0.1\\lib\\site-packages (from requests<3.0.0,>=2.0.1->requests_toolbelt==1.0.0) (3.10)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in .\\langchain_v0.1\\lib\\site-packages (from requests<3.0.0,>=2.0.1->requests_toolbelt==1.0.0) (2.2.3)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in .\\langchain_v0.1\\lib\\site-packages (from requests<3.0.0,>=2.0.1->requests_toolbelt==1.0.0) (2024.8.30)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 23.2.1 -> 24.2\n",
      "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
     ]
    }
   ],
   "source": [
    "! pip install requests_toolbelt==1.0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain.agents import load_tools, initialize_agent, AgentType\n",
    "from langchain.utilities import GraphQLAPIWrapper\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-4-1106-preview\",\n",
    "    )\n",
    "\n",
    "tools = load_tools(\n",
    "    [\"graphql\"],\n",
    "    graphql_endpoint=\"https://swapi-graphql.netlify.app/.netlify/functions/index\",\n",
    ")\n",
    "\n",
    "agent = initialize_agent(\n",
    "    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mTo answer the question, I need to query the GraphQL database for the titles of all the Star Wars films. I will write a GraphQL query to retrieve the titles of the films.\n",
      "\n",
      "Action: query_graphql\n",
      "Action Input: query { allFilms { films { title } } }\u001B[0m\n",
      "Observation: \u001B[36;1m\u001B[1;3m\"{\\n  \\\"allFilms\\\": {\\n    \\\"films\\\": [\\n      {\\n        \\\"title\\\": \\\"A New Hope\\\"\\n      },\\n      {\\n        \\\"title\\\": \\\"The Empire Strikes Back\\\"\\n      },\\n      {\\n        \\\"title\\\": \\\"Return of the Jedi\\\"\\n      },\\n      {\\n        \\\"title\\\": \\\"The Phantom Menace\\\"\\n      },\\n      {\\n        \\\"title\\\": \\\"Attack of the Clones\\\"\\n      },\\n      {\\n        \\\"title\\\": \\\"Revenge of the Sith\\\"\\n      }\\n    ]\\n  }\\n}\"\u001B[0m\n",
      "Thought:\u001B[32;1m\u001B[1;3mI have obtained the titles of the Star Wars films. Now I will translate each title into Chinese.\n",
      "\n",
      "Final Answer: The titles of the Star Wars films in Chinese are:\n",
      "- 新希望 (A New Hope)\n",
      "- 帝国反击战 (The Empire Strikes Back)\n",
      "- 绝地归来 (Return of the Jedi)\n",
      "- 幽灵的威胁 (The Phantom Menace)\n",
      "- 克隆人的进攻 (Attack of the Clones)\n",
      "- 西斯的复仇 (Revenge of the Sith)\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    }
   ],
   "source": [
    "graphql_fields = \"\"\"allFilms {\n",
    "    films {\n",
    "      title\n",
    "      director\n",
    "      releaseDate\n",
    "      speciesConnection {\n",
    "        species {\n",
    "          name\n",
    "          classification\n",
    "          homeworld {\n",
    "            name\n",
    "          }\n",
    "        }\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "\n",
    "\"\"\"\n",
    "\n",
    "suffix = \"Search for the titles of all the stawars films stored in the graphql database that has this schema,and answer in chinese:\"\n",
    "\n",
    "try:\n",
    "    output = agent.invoke(suffix + graphql_fields)\n",
    "except Exception as e:\n",
    "    print(e)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
